Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
54.55% covered (warning)
54.55%
12 / 22
CRAP
74.14% covered (warning)
74.14%
43 / 58
ProductModelRepository
0.00% covered (danger)
0.00%
0 / 1
54.55% covered (warning)
54.55%
12 / 22
45.57
74.14% covered (warning)
74.14%
43 / 58
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
7 / 7
 getItemsFromIdentifiers
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getIdentifierProperties
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 findOneByIdentifier
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 find
0.00% covered (danger)
0.00%
0 / 1
2.06
75.00% covered (warning)
75.00%
3 / 4
 findAll
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 findBy
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 findOneBy
0.00% covered (danger)
0.00%
0 / 1
2.06
75.00% covered (warning)
75.00%
3 / 4
 findSiblingsProductModels
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 countRootProductModels
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 findChildrenProductModels
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 findDescendantProductIdentifiers
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 findByIdentifiers
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 findChildrenProducts
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 searchRootProductModelsAfter
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 2
 findSubProductModels
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 findRootProductModels
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 findProductModelsForFamilyVariant
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 2
 searchLastLevelByCode
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getFilteredProductModel
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getFilteredProductModels
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 getFilteredProducts
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
<?php
declare(strict_types=1);
/*
 * This file is part of the Akeneo PIM Enterprise Edition.
 *
 * (c) 2017 Akeneo SAS (http://www.akeneo.com)
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Akeneo\Pim\Permission\Bundle\Persistence\ORM\EntityWithValue;
use Akeneo\Pim\Enrichment\Component\Product\Model\ProductInterface;
use Akeneo\Pim\Enrichment\Component\Product\Model\ProductModelInterface;
use Akeneo\Pim\Enrichment\Component\Product\Repository\ProductModelRepositoryInterface;
use Akeneo\Pim\Permission\Component\Attributes;
use Akeneo\Pim\Permission\Component\Authorization\DenyNotGrantedCategorizedEntity;
use Akeneo\Pim\Permission\Component\Factory\FilteredEntityFactory;
use Akeneo\Pim\Structure\Component\Model\FamilyVariantInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
 * Decorates CE product model repository to apply permissions.
 *
 * @author Marie Bochu <marie.bochu@akeneo.com>
 */
class ProductModelRepository extends EntityRepository implements ProductModelRepositoryInterface
{
    /** @var ProductModelRepositoryInterface */
    private $productModelRepository;
    /** @var FilteredEntityFactory */
    private $filteredProductFactory;
    /** @var FilteredEntityFactory */
    private $filteredProductModelFactory;
    /** @var DenyNotGrantedCategorizedEntity */
    private $denyNotGrantedCategorizedEntity;
    /** @var AuthorizationCheckerInterface  */
    private $authorizationChecker;
    /**
     * @param EntityManagerInterface          $em
     * @param ProductModelRepositoryInterface $productModelRepository
     * @param FilteredEntityFactory           $filteredProductModelFactory
     * @param FilteredEntityFactory           $filteredProductFactory
     * @param DenyNotGrantedCategorizedEntity $denyNotGrantedCategorizedEntity
     * @param string                          $entityName
     * @param AuthorizationCheckerInterface   $authorizationChecker
     */
    public function __construct(
        EntityManagerInterface $em,
        ProductModelRepositoryInterface $productModelRepository,
        FilteredEntityFactory $filteredProductModelFactory,
        FilteredEntityFactory $filteredProductFactory,
        DenyNotGrantedCategorizedEntity $denyNotGrantedCategorizedEntity,
        string $entityName,
        AuthorizationCheckerInterface $authorizationChecker
    ) {
        parent::__construct($em, $em->getClassMetadata($entityName));
        $this->productModelRepository = $productModelRepository;
        $this->filteredProductFactory = $filteredProductFactory;
        $this->filteredProductModelFactory = $filteredProductModelFactory;
        $this->denyNotGrantedCategorizedEntity = $denyNotGrantedCategorizedEntity;
        $this->authorizationChecker = $authorizationChecker;
    }
    /**
     * {@inheritdoc}
     */
    public function getItemsFromIdentifiers(array $identifiers)
    {
        $productModels = $this->productModelRepository->getItemsFromIdentifiers($identifiers);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function getIdentifierProperties()
    {
        return $this->productModelRepository->getIdentifierProperties();
    }
    /**
     * {@inheritdoc}
     */
    public function findOneByIdentifier($identifier)
    {
        $productModel = $this->productModelRepository->findOneByIdentifier($identifier);
        if (null === $productModel) {
            return null;
        }
        return $this->getFilteredProductModel($productModel);
    }
    /**
     * {@inheritdoc}
     */
    public function find($id, $lockMode = null, $lockVersion = null)
    {
        $productModel = $this->productModelRepository->find($id);
        if (null === $productModel) {
            return  null;
        }
        return $this->getFilteredProductModel($productModel);
    }
    /**
     * {@inheritdoc}
     */
    public function findAll()
    {
        $productModels = $this->productModelRepository->findAll();
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $productModels = $this->productModelRepository->findBy($criteria, $orderBy, $limit, $offset);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findOneBy(array $criteria, array $orderBy = null)
    {
        $productModel = $this->productModelRepository->findOneBy($criteria);
        if (null === $productModel) {
            return null;
        }
        return $this->getFilteredProductModel($productModel);
    }
    /**
     * {@inheritdoc}
     */
    public function findSiblingsProductModels(ProductModelInterface $productModel): array
    {
        $productModels = $this->productModelRepository->findSiblingsProductModels($productModel);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function countRootProductModels(): int
    {
        return $this->productModelRepository->countRootProductModels();
    }
    /**
     * {@inheritdoc}
     */
    public function findChildrenProductModels(ProductModelInterface $productModel): array
    {
        $productModels = $this->productModelRepository->findChildrenProductModels($productModel);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findDescendantProductIdentifiers(ProductModelInterface $productModel): array
    {
        return $this->productModelRepository->findDescendantProductIdentifiers($productModel);
    }
    /**
     * {@inheritdoc}
     */
    public function findByIdentifiers(array $codes): array
    {
        $productModels = $this->productModelRepository->findByIdentifiers($codes);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findChildrenProducts(ProductModelInterface $productModel): array
    {
        $products = $this->productModelRepository->findChildrenProducts($productModel);
        return $this->getFilteredProducts($products);
    }
    /**
     * {@inheritdoc}
     */
    public function searchRootProductModelsAfter(?ProductModelInterface $product, int $limit): array
    {
        $productModels = $this->productModelRepository->searchRootProductModelsAfter($product, $limit);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findSubProductModels(FamilyVariantInterface $familyVariant): array
    {
        $productModels = $this->productModelRepository->findSubProductModels($familyVariant);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findRootProductModels(FamilyVariantInterface $familyVariant): array
    {
        $productModels = $this->productModelRepository->findRootProductModels($familyVariant);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function findProductModelsForFamilyVariant(FamilyVariantInterface $familyVariant, ?string $search = null): array
    {
        $productModels = $this->productModelRepository->findProductModelsForFamilyVariant($familyVariant, $search);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * {@inheritdoc}
     */
    public function searchLastLevelByCode(FamilyVariantInterface $familyVariant, string $search, int $limit, int $page = 0): array
    {
        $productModels = $this->productModelRepository->searchLastLevelByCode($familyVariant, $search, $limit, $page);
        return $this->getFilteredProductModels($productModels);
    }
    /**
     * Get a single product model filtered with only granted data
     *
     * @param ProductModelInterface $productModel
     *
     * @return ProductModelInterface
     */
    private function getFilteredProductModel(ProductModelInterface $productModel): ProductModelInterface
    {
        $this->denyNotGrantedCategorizedEntity->denyIfNotGranted($productModel);
        return $this->filteredProductModelFactory->create($productModel);
    }
    /**
     * Get product models filtered with only granted data
     *
     * @param ProductModelInterface[] $productModels
     *
     * @return array
     */
    private function getFilteredProductModels(array $productModels): array
    {
        $filteredProductModels = [];
        foreach ($productModels as $productModel) {
            $this->denyNotGrantedCategorizedEntity->denyIfNotGranted($productModel);
            $filteredProductModels[] = $this->filteredProductModelFactory->create($productModel);
        }
        return $filteredProductModels;
    }
    /**
     * Get product filtered with only granted data
     *
     * @param ProductInterface[] $products
     *
     * @return array
     */
    private function getFilteredProducts(array $products): array
    {
        $filteredProducts = [];
        foreach ($products as $product) {
            if ($this->authorizationChecker->isGranted(Attributes::VIEW, $product)) {
                $filteredProducts[] = $this->filteredProductFactory->create($product);
            }
        }
        return $filteredProducts;
    }
}